// Copyright (C) joyinter
// All rights reserved.
// 
// Author : Jiang Li
// Date   : 2004-6-11

#ifndef __THREAD_H_COMMON_BASE__
#define __THREAD_H_COMMON_BASE__

#pragma once

//##ModelId=44C4B5F501D4
class CJoyCriticalSection
{
protected:
	//##ModelId=44C4B5F501D5
    volatile CRITICAL_SECTION m_cs;
public:
	//##ModelId=44C4B5F501E4
    CJoyCriticalSection();
	//##ModelId=44C4B5F501E5
    ~CJoyCriticalSection();
	//##ModelId=44C4B5F501E6
    void Lock();
	//##ModelId=44C4B5F501E7
    void Unlock();
	//##ModelId=44C4B5F501E8
    bool TryLock();
};

//##ModelId=44C4B5F501F4
class CJoyAutoCS
{
protected:
	//##ModelId=44C4B5F501F6
    CJoyCriticalSection&  m_cs;

	//##ModelId=44C4B5F50203
    void operator = (const CJoyAutoCS& a);
public:
	//##ModelId=44C4B5F50205
    CJoyAutoCS(CJoyCriticalSection& cs):
        m_cs(cs)
    {
        m_cs.Lock();
    }
	//##ModelId=44C4B5F50207
    ~CJoyAutoCS()
    {
        m_cs.Unlock();
    }
};

extern "C" long __cdecl _InterlockedIncrement(long volatile *);
extern "C" long __cdecl _InterlockedDecrement(long volatile *);

#pragma intrinsic(_InterlockedIncrement)
#pragma intrinsic(_InterlockedDecrement)

//##ModelId=44C4B5F50213
class CJoyAtomCount
{
protected:
	//##ModelId=44C4B5F50214
    long volatile m_nValue;
public:
	//##ModelId=44C4B5F50222
    CJoyAtomCount(long v = 0):
        m_nValue(v)
    {
    }
	//##ModelId=44C4B5F50224
    long operator++()
    {
        return ::_InterlockedIncrement(&m_nValue);
    }
	//##ModelId=44C4B5F50225
    long operator--()
    {
        return ::_InterlockedDecrement(&m_nValue);
    }
	//##ModelId=44C4B5F50226
    long operator ++ (int)
    {
        return ::_InterlockedIncrement(&m_nValue)-1;
    }
	//##ModelId=44C4B5F50233
    long operator -- (int)
    {
        return ::_InterlockedDecrement(&m_nValue)+1;
    }
	//##ModelId=44C4B5F50235
    operator long() const
    {
        return m_nValue;
    }
	//##ModelId=44C4B5F50237
    long operator = (long v)
    {
        m_nValue = v;
        return v;
    }
};

#endif  // __THREAD_H_COMMON_BASE__
